2015-08-19

創用 CC 授權條款

Function / Program in R

Program:

程式:

資料 or 資料結構





Data Structure:

剛剛上一位講者: Ning 已經教過了,忘了要記得複習喔!

小小複習一下:


numeric1 = c(2, 3, 5) 

string1 = c("aa", "bb", "cc") 

boolean1 = c(TRUE, FALSE, TRUE) 

data1 = data.frame(numeric1, string1, boolean1)

##   number1 string1 boolean1
## 1       2      aa     TRUE
## 2       3      bb    FALSE
## 3       5      cc     TRUE

什麼叫程式





目的是用來處理「特定資料」,

根據演算法將多個函式或是指令組成的集合




簡單說,寫一個程式,其實和 寫一段文章,或是一篇小說差不多,

Function 或 演算法





數學上叫函數,

程式語言中叫函式

為什麼要用function:



1. 可以把相同「目的」指令和資料整理在一起


2. 可重複使用


3. 可方便程式的閱讀


by 民明書房 Noah

function的用法:

可用R來查詢定義:




?function(){}


用法:




函式名稱 = function(引數) {

  程式的內容........

}

愛護生命,建議千萬不要用中文當作變數及函式名字,現在出現中文只是用來說明

範例1:Hello World

第一個R的程式:





請在R 中顯示:Hello World, R


Hello World







  print("Hello World, R")

Hello World





helloworld <- function(){

  print("Hello World, R")

}

範例:可以帶入變數


helloworld <- function(my_name){

  print(paste("Hello World,", my_name))
}

執行:

helloworld("DSC2015")

## [1] "Hello World, DSC2015"

helloworld:函式名稱,
my_name:此函式所帶入的參數,

範例2:

顯示現在的時間:


print("現在的時間和日期是:")

print(date())


## [1] "現在的時間和日期是:"
## [1] "Wed Aug 19 07:29:22 2015"

分別顯示現在的日期和時間:


    print("現在的日期是:")
    print(paste(substr(date(),21,24), substr(date(),5,10), substr(date(),1,3)))

## [1] "現在的日期是:"
## [1] "2015 Aug 19 Wed"

    print("現在的時間是:")
    print(substr(date(),12,19))

## [1] "現在的時間是:"
## [1] "07:29:22"

用一個名字將上面的程式包起來


now1 <- function(){

    print("現在的日期是:")
    print(paste(substr(date(),21,24), substr(date(),5,10), substr(date(),1,3)))
    print("現在的時間是:")
    print(substr(date(),12,19))
}

使用function

在console下輸入指定的名稱和括號:

now_time()

## [1] "現在的日期是:"
## [1] "2015 Aug 19 Wed"
## [1] "現在的時間是:"
## [1] "07:29:22"

程式儲存及執行

用R studio 或用文字編輯器存成.R檔

執行R程式:

用source指令:

source("iris.r")

Q & A

課程預告:

課程預告:

ETL(Extract, Transform and Load ) on R, by Aha

課程預告:

ETL(Extract, Transform and Load ) on R, by Aha

R Visualzation : using ggplot2, by Mansun/Ben/Kyle

課程預告:

ETL(Extract, Transform and Load ) on R, by Aha

R Visualzation : using ggplot2, by Mansun/Ben/Kyle

R 火力展示 / 閃電秀, by c3h3

課程預告:

ETL(Extract, Transform and Load ) on R, by Aha

R Visualzation : using ggplot2, by Mansun/Ben/Kyle

R 火力展示 / 閃電秀, by c3h3

R 專題實習 , by wush

END…..?

現在已經把R的基本的function和data都介紹完了,

相信有不少人應該可以自豪的說:學了R以後,

那….我來幹嘛?

泛舟嗎?

讓我們來寫一些 R 的程式吧!~

對了,

如果課程中有任何問題都可以問助教
R社群最神奇的地方就是:







助教什麼都會!

貼心小提醒1:

遇到不會的指令可以用下面方法查詢:

『?』+『指令』

『example』『(』+『指令』+『)』

ex:

?list
example(factor)

貼心小提醒2:







善用「tab」按鍵

Syllabus

Syllabus1:


Function


編輯撰寫屬於你的第一個R程式

Syllabus2:

Flow Control


判斷條件控制 
- if / else

迴圈控制 
- for(),
- while(),

Syllabus3:

Debug and Error/Exception Handling


- 除錯(找蟲)
- debug() / undebug()

程式錯誤及例外處理
try() / tryCatch()

Flow Control:程式流程控制:

if / else:

==> 如果xxxx,那就xxxx,否則xxxx


Syntex:

    if (condition_1){
        #Do something here....
    } else if (conditon_2){
        #Do something here
    } else {
        #Do something here
    }


Note: **else if** and **else** are optional.

邏輯:




[TRUE] or [T]




[FALSE] or [F]

if /else 邏輯判斷符號

"==":等於

"1" == "1"


[1] TRUE


"1" == "2"


[1] FALSE

if / else 邏輯判斷符號

"<=":小於等於

"1" <= "1"


[1] TRUE


"1" <= "2"


[1] FALSE

if / else 邏輯判斷符號

"<":小於

"1" < "2"


[1] TRUE


"1" < "1"


[1] FALSE

if / else 邏輯判斷符號

">=":大於等於

"1" >= "1"


[1] TRUE


"1" >= "2"


[1] FALSE

if / else 邏輯判斷符號

">":大於

"2" > "1"


[1] TRUE


"1" > "1"


[1] FALSE

if / else 邏輯判斷符號

"!=":不等於

"2" != "1"


[1] TRUE


"1" != "1"


[1] FALSE

if / else 邏輯判斷符號

"&":邏輯中的「且」 或「and」

"1" == "1" && "2" == "2"


[1] TRUE


("1" == "2")  &&  ("2" == "2")


[1] FALSE

if / else 邏輯判斷符號

"|":邏輯中的「或」 或「or」

("1" == "1")  ||  ("2" == "2")


[1] TRUE


("1" == "2")  ||  ("2" == "2")


[1] TRUE


("1" == "2")  ||  ("2" == "3")


[1] FALSE

那會了if和邏輯符號,可以怎麼用?

範例:小明看電影

小明現在6歲,電影小小兵是保護級,

那小明可不可以看電影小小兵?

用一般的方法說:




如果小明滿7歲的話,那就可以看小小兵,如果沒有的話,那就不能看。

條件判斷1

1. 小明6歲


小明 = 6

2. 保護級條件:

未滿7歲之兒童不宜觀賞,
7歲以上未滿12歲之少年需父母或師長輔導觀賞。

不能看
保護級年紀規定 = 大於等於7歲,而且也要小於12歲
保護級最低年紀規定 = 大於等於7歲
保護級需要父母陪同的最高年紀規定 = 小於12歲
保護級不需要父母陪同的年紀規定 = 12歲以上

如果小明>7歲的話:


if (小明 >= 保護級最低年紀規定){
    print(可以看)
}"

如果小明<7歲的話:


if (小明 < 保護級最低年紀規定){
print(就是不讓你看)
}

那就寫成程式吧:

註:愛護生命,變數請一定用英文


小明 = 7;
保護級最低年紀 = 7;
if(小明 > 保護級最低年紀) {
  print("YES, 小明 可以看~~")
} 

[1] 小明可以看


if(小明 < 保護級最低年紀) {
  print("NO, T_T 小明 不能看")
} 

[1] __________

我知道上面的例子有點簡單,

範例:閏年

請判斷輸入的年份是不是閏年?


目前使用的格里曆閏年規則如下:


西元年份除以400可整除=閏年。

西元年份除以4可整除但除以100不可整除=閏年。

西元年份除以4不可整除=平年。

西元年份除以100可整除但除以400不可整除=平年


https://zh.wikipedia.org/zh-tw/%E9%97%B0%E5%B9%B4

^^ 由小道大 (先判斷小圈圈)) ︿︿由大道小 (先判斷大圈圈)

step1: 年份除以400可整除=閏年

假設年份為2015年


『如果』 『年份』 『除以』 『400』 『餘數等於』 『0』 

『等於』『閏年』

變成程式的話就是:





如果((年份 對後數取餘數 400) 等於 0){ 

是不是閏年 = 是

}

變成程式的話就是:





if ((year    %%       400)  == 0){ 

lear_year = TRUE

}

step2:西元年份除以4可整除,但除以100可整除=不是閏年。

可以用or


if((year %% 4) == 0){ 

print("Leap year")
}
if((year %% 100) == 0){

print("NOT leap year")
}

咦?好像有地方怪怪的

除以4可整除,那除以100一定也可以整除啊

else()出現了


if ((year1 %% 4)==0){ 
if ((year1 %% 100)==0){
print("NOT leap year")
} else {
print("Leap year")
} }

step4:西元年份除以100可整除,但除以400不可整除=不是閏年。

聰明的各位應該發現到這邊有好幾個判斷出現了,

還記得前面講過有四個條件嗎?


if ((year1 %% 4)==0){
  if ((year1 %% 100)==0){
    if ((year1 %% 400)==0)
      print("Leap year")
    else
      print("Not leap year")
  } else {
    print("Leap year")
  }
} else {
  print("Not leap year")
}

遊戲時間

猜數字

  1. 猜數字的小遊戲

  2. 猜幾A幾B的遊戲

  3. 讓電腦比賽猜幾A幾B的遊戲 (還在研究中)

  4. 圈叉遊戲

  5. 五子旗

︿︿舉例:如果要判斷100個年份 # 迴圈

迴圈說明

某個動作重複做多少次,可減少重複寫code的時間

迴圈使用的時機

1. 重複有限次數 (for loop)

2. 重複次數不能確定 (while loop)

3. 重複無限次數 (while loop)

for 迴圈

1. 開始條件


2. 次數累計


3. 停止條件

for()

for (累進變數 in 開始條件:終止條件 )


for(x in 1:10) {
  print(x)
}

## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10

for(): ex2

for ( 累進變數 in 向量 )


c1 = c(1:10)
for(x in c1) {
  print(x)
}

## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10

while()

while (條件不成立的話,就停止)


while(判斷式) {}

如果判斷式不成立就停止,否則一直執行迴圈的程式

最簡單的無限迴圈





while(1){

    print("I love R")   

}

break:

當進入迴圈時,如果想離開迴圈的話,這時後可以用break跳出迴圈

會了for,可以怎麼用?

這是copy-paste沒錯

算有多少個閏年

請說明一段時間內,有多少年是閏年

提醒:可以用for來持續檢查某一年是否是閏年,例如:開始年:1000,結束年:2015



for(年 in 開始年:結束年){ 

判斷是否是閏年

如果是閏年則次數 + 1
}

用之前講的判斷式


yearS = 1000 # 或是可以輸入:as.integer(readline("input start year:")) 來自己輸入開始年
yearE = 2015 # 或是可以輸入:as.integer(readline("input end year:")) 來輸入結束年
year_cnt=0


for (n in yearS:yearE){ 
    if ((year1 %% 4)==0){
        if ((year1 %% 100)==0){
            if ((year1 %% 400)==0)
                is_leap_year = TRUE
            else
                is_leap_year = FALSE
            } else {
                is_leap_year = TRUE
            }
        } else {
        is_leap_year = FALSE
    }   
    if (is_leap_year == TRUE)
    year_cnt = year_cnt + 1 
  }
}
paste("總共有:", year_cnt," 個閏年")

## [1] "總共有: 246  個閏年"

範例:閏年判斷程式:

把之前的閏年判斷包成函式:leap_year()


leap_year = function(year1){
    if ((year1 %% 4)==0){
      if ((year1 %% 100)==0){
        if ((year1 %% 400)==0)
          return TRUE   # 是閏年
        else
          return FALSE  # 不是閏年
      } else {
        return TRUE     # 是閏年
      }
    } else {
      return FALSE      # 不是閏年
    }
}

把 leap_year()放到for迴圈中


yearS = 1000 # 或是可以輸入:as.integer(readline("input start year:")) 來自己輸入開始年
yearE = 2015 # 或是可以輸入:as.integer(readline("input end year:")) 來輸入結束年
year_cnt=0


for (n in yearS:yearE){
  if (leap_year(n)){
    year_cnt = year_cnt+1
  }
}
paste("總共有:", year_cnt," 個閏年")

## [1] "總共有:   個閏年"

延伸題目:

除了多少年之外,還想知道想知道哪些年是閏年

Debug:除錯

為什麼要除錯:

每天都在問神奇海螺

E=(MC)^2

人都可能被劈腿,手一定有機會出鎚,

Debug 常用指令:





debug(fun) 

undebug(fun)

使用方法:


debug(now_time) 
now_time()
undebug(now_time)

測試:

用debug來測試前面好的閏年程式:leap_year()

Error / Exception Handling:錯誤管理

Error/Exception Handling

輸入範例

inputs = list(1, 2, 4, -5, 'oops', 0, 10) 
for(input in inputs) {
print(paste("log of", input, "=", log(input)))
}

輸出結果:Error


[1] "log of 1 = 0"
[1] "log of 2 = 0.693147180559945"
[1] "log of 4 = 1.38629436111989"
[1] "log of -5 = NaN"


Error in log(input) : non-numeric argument 
to mathematical function
此外: Warning message:
In log(input) : 產生了 NaNs

RBlogger的範例:

http://www.r-bloggers.com/error-handling-in-r/

Error Handling: try()


inputs = list(1, 2, 4, -5, 'oops', 0, 10)

for(input in inputs) {

  try(print(paste("log of", input, "=", log(input))))
}

## [1] "log of 1 = 0"
## [1] "log of 2 = 0.693147180559945"
## [1] "log of 4 = 1.38629436111989"
## Warning in log(input): NaNs produced
## [1] "log of -5 = NaN"
## [1] "log of 0 = -Inf"
## [1] "log of 10 = 2.30258509299405"

Error Handling: 使用tryCatch()來顯示錯誤

data_in = list(1, 2, 4, -5, 'oops', 0, 10)

func_error = function(e){
    print("this is a ERROR!!!")
}
func_warning = function(w){
    print("just a wraning")
}
for(input in data_in) {
  tryCatch(print(paste("log of", input, "=", log(input))),
  warning = func_warning ,   error = func_error)
}
## [1] "log of 1 = 0"
## [1] "log of 2 = 0.693147180559945"
## [1] "log of 4 = 1.38629436111989"
## [1] "just a wraning"
## [1] "this is a ERROR!!!"
## [1] "log of 0 = -Inf"
## [1] "log of 10 = 2.30258509299405"

小天使複習班:

R常用指令1

R常用指令2

小提醒:data.frame()


num1 = c(2, 3, 5) 

str1 = c("aa", "bb", "cc")

logic1 = c(TRUE, FALSE, TRUE)

df1 = data.frame(num1, str1, logic1)

# df1表示把data.frame()括號內的資料結合成為data.frame型態
##   num1 str1 logic1
## 1    2   aa   TRUE
## 2    3   bb  FALSE
## 3    5   cc   TRUE

比較c() vs data.frame()


num1 = c(2, 3, 5) 

str1 = c("aa", "bb", "cc")

logic1 = c(TRUE, FALSE, TRUE)

df2 = c(num1, str1, logic1)

# df2表示為c()括號中向量資料的結合
## [1] "2"     "3"     "5"     "aa"    "bb"    "cc"    "TRUE"  "FALSE" "TRUE"

比較rbind() vs data.frame()


num1 = c(2, 3, 5) 

str1 = c("aa", "bb", "cc")

logic1 = c(TRUE, FALSE, TRUE)

df3 = rbind(num1, str1, logic1)
# df3表示為rbind()括號中資料的結合
##        [,1]   [,2]    [,3]  
## num1   "2"    "3"     "5"   
## str1   "aa"   "bb"    "cc"  
## logic1 "TRUE" "FALSE" "TRUE"

小提醒:讀取檔案、表格:

讀取R檔並執行

如果想讀取儲存在硬碟的R檔的話,可以用source指令:


source("iris.r")

讀取CSV

CSV:(Comma-separated values:逗號分隔數值)

表格名稱 = read.csv("讀取的檔案")


iris_csv = read.csv("iris.csv") 

View(iris_csv)

一般文字表格

表格名稱 = read.table("讀取的檔案")


iris_tab = read.table("iris.txt")

View(iris_tab)

其他檔案:如excel等

表格名稱 = read.xls("讀取的檔案")

注意:這個需要額外的套件來支援excel格式,請先執行:library(gdata)
注意2:gdata套件的read.xls只能讀excel檔案中第一頁sheet,


library(gdata)

iris_xls = read.xls("iris.xls")

View(iris_xls)

課程再預告

課程預告:

ETL(Extract, Transform and Load ) on R, by Aha

課程預告:

ETL(Extract, Transform and Load ) on R, by Aha

R Visualzation : using ggplot2, by Mansun/Ben/Kyle

課程預告:

ETL(Extract, Transform and Load ) on R, by Aha

R Visualzation : using ggplot2, by Mansun/Ben/Kyle

R 火力展示 / 閃電秀, by c3h3

課程預告:

ETL(Extract, Transform and Load ) on R, by Aha

R Visualzation : using ggplot2, by Mansun/Ben/Kyle

R 火力展示 / 閃電秀, by c3h3

R 專題實習 , by wush

Q & A

END!